package com.zyw.module.console.admin.auth;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.zyw.module.console.user.po.User;
import com.zyw.module.console.user.service.UserService;
import com.zyw.net.exception.RequestException;
import com.zyw.net.http.HttpClient;
import com.zyw.net.http.HttpParams;
import com.zyw.security.shiro.LoginFrom;
import com.zyw.security.shiro.web.authc.AuthInfo;
import com.zyw.security.shiro.web.authc.AuthService;
import com.zyw.utils.PropertyHolder;
import org.apache.shiro.authc.AccountException;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.List;

/**
 * @author zhangyw
 * @version 2018/2/28 15:59
 */
@Component
public class MiniAppsAuthcService implements AuthService {

    private static Logger logger = org.slf4j.LoggerFactory.getLogger(AuthService.class);

    private static HttpClient httpClient = HttpClient.newHttpClient();
    private static final String miniappAuthUrl = "https://api.weixin.qq.com/sns/jscode2session";

    @Autowired
    private UserService userService;

    /**
     * 获取用户认证信息，通过principal 去数据库或者第三方服务查询
     *
     * @param principal 访问信息
     * @return auth info
     */
    @Override
    public AuthInfo getAuthInfo(Object principal) {

        HttpParams httpParams = HttpParams.create();
        httpParams.addParameter("appid", PropertyHolder.getString("miniapp.appid"));
        httpParams.addParameter("secret", PropertyHolder.getString("miniapp.secret"));
        httpParams.addParameter("js_code", (String) principal);
        httpParams.addParameter("grant_type", "authorization_code");

        try {
            String res = httpClient.get(miniappAuthUrl, httpParams);
            JSONObject jsonObject = JSON.parseObject(res);
            if (jsonObject.getInteger("errcode") == null) { // errorcode 不存在 说明返回正常
                String openid = jsonObject.getString("openid");
                String session_key = jsonObject.getString("session_key");
                String unionid = jsonObject.getString("unionid");

                AuthInfo authInfo = new AuthInfo();
                authInfo.addAllAttributes(jsonObject);
                authInfo.setAuthType(LoginFrom.wxminiapp.name());

                List<User> users = userService.findByMiniappOpenid(openid);
                if (users != null && !users.isEmpty()) { // exist
                    User user = users.get(0);
                    authInfo.setUserid(user.getId());
                    authInfo.setUsername(user.getUsername());
                    authInfo.setPassword(user.getPassword());
                    authInfo.setStatus(user.getStatus());
                    return authInfo;
                } else { // TODO not exist , do register
                    authInfo.setAnon(true); // 新用户，匿名访问
                    return authInfo;
                }
            } else {
                throw new AccountException(jsonObject.getString("errmsg"));
            }
        } catch (RequestException e) {
            logger.error("miniapp authorization has ocour an error {}", e);
            throw new AccountException(e);
        }
    }

    /**
     * 获取用户，服务器端存储的 令牌 credentials
     *
     * @param principal 访问信息
     * @return credentials
     */
    @Override
    public String getCredentials(Object principal) {
        return null;
    }

    /**
     * 验证用户的credentials
     *
     * @param principal         用户信息
     * @param targetCredentials 用户输入的凭证
     * @param sourceCredentials 服务端留存的凭证, 可为空
     * @return true right credentials
     */
    @Override
    public boolean validCredentials(String principal, String targetCredentials, String sourceCredentials) {
        return false;
    }
}
